package com.smart.campus.web.controller.school;

import java.io.*;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.smart.campus.common.config.Global;
import com.smart.campus.common.utils.DateUtils;
import com.smart.campus.common.utils.StringUtils;
import com.smart.campus.framework.util.ShiroUtils;
import com.smart.campus.framework.web.service.DictService;
import com.smart.campus.school.domain.*;
import com.smart.campus.school.domain.vo.CourseItemConfigVo;
import com.smart.campus.school.domain.vo.CourseItemInfoVo;
import com.smart.campus.school.domain.vo.CourseMainConfigVo;
import com.smart.campus.school.domain.vo.CourseStatisticsVo;
import com.smart.campus.school.service.*;
import com.smart.campus.system.domain.SysDictData;
import com.smart.campus.system.domain.SysUser;
import com.smart.campus.system.service.ISysUserService;
import com.smart.campus.web.utils.PdfUtil;
import com.smart.campus.web.utils.SchoolUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.smart.campus.common.annotation.Log;
import com.smart.campus.common.enums.BusinessType;
import com.smart.campus.common.core.controller.BaseController;
import com.smart.campus.common.core.domain.AjaxResult;
import com.smart.campus.common.utils.poi.ExcelUtil;
import com.smart.campus.common.core.page.TableDataInfo;

import javax.servlet.http.HttpServletResponse;

/**
 * 排课规则主Controller
 * 
 * @author Zhihe.Li
 * @date 2020-06-14
 */
@Controller("course")
@RequestMapping("/school/courseConfig")
public class CourseMainConfigController extends BaseController
{
    private String prefix = "school/courseConfig";

    @Autowired
    private ICourseMainConfigService courseMainConfigService;

    @Autowired
    private ICourseItemConfigService courseItemConfigService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private IClassInfoService classInfoService;
    @Autowired
    private DictService dictService;


    @Autowired
    private IPersonnelInfoService personnelInfoService;

    @Autowired
    private ICourseItemTimeService courseItemTimeService;
    //调课服务
    @Autowired
    private IAdjustCourseService adjustCourseService;
    @RequiresPermissions("school:courseConfig:view")
    @GetMapping()
    public String courseConfig()
    {
        return prefix + "/courseConfig";
    }

    /**
     * 查询排课规则主列表
     */
    @RequiresPermissions("school:courseConfig:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(CourseMainConfigVo courseMainConfig)
    {
        startPage();
        List<CourseMainConfigVo> list = courseMainConfigService.selectCourseMainConfigList(courseMainConfig);
        return getDataTable(list);
    }

    /**
     * 导出排课规则主列表
     */
    @RequiresPermissions("school:courseConfig:export")
    @Log(title = "排课规则主", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(CourseMainConfigVo courseMainConfig)
    {
        List<CourseMainConfigVo> list = courseMainConfigService.selectCourseMainConfigList(courseMainConfig);
        ExcelUtil<CourseMainConfigVo> util = new ExcelUtil<CourseMainConfigVo>(CourseMainConfigVo.class);
        return util.exportExcel(list, "courseConfig");
    }

    /**
     * 新增排课规则主
     */
    @GetMapping("/add")
    public String add()
    {
        return prefix + "/add";
    }

    /**
     * 新增保存排课规则主
     */
    @RequiresPermissions("school:courseConfig:add")
    @Log(title = "排课规则主", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(CourseMainConfigVo courseMainConfig)
    {
        courseMainConfig.setSchoolId(SchoolUtil.getSchoolId());
        courseMainConfig.setCreateBy(ShiroUtils.getSysUser().getUserName());
        courseMainConfig.setCreateTime(DateUtils.getNowDate());
        courseMainConfig.setState(0);
        return toAjax(courseMainConfigService.insertCourseMainConfig(courseMainConfig));
    }

    /**
     * 修改排课规则主
     */
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap mmap)
    {
        CourseMainConfigVo courseMainConfig = courseMainConfigService.selectCourseMainConfigById(id);
        mmap.put("courseMainConfig", courseMainConfig);
        return prefix + "/edit";
    }

    @Log(title = "复制课表", businessType = BusinessType.OTHER)
    @RequiresPermissions("school:courseConfig:edit")
    @ResponseBody
    @GetMapping("/copy/{id}")
    public AjaxResult copy(@PathVariable("id") Long id)
    {
        AjaxResult res = AjaxResult.success();
        CourseMainConfigVo courseMainConfigVo = courseMainConfigService.selectCourseMainConfigById(id);

        String name = "拷贝";
        if(!StringUtils.isEmpty(courseMainConfigVo.getName())){
            name+=courseMainConfigVo.getName();
        }
        courseMainConfigVo.setName(name);
        courseMainConfigVo.setId(null);
        courseMainConfigVo.setState(0);
        courseMainConfigService.insertCourseMainConfig(courseMainConfigVo);
        CourseMainConfigVo l1 = courseMainConfigService.selectCourseMainConfigItem(courseMainConfigVo);
        Long newId = l1.getId();
        CourseItemConfigVo itm = new CourseItemConfigVo();
        itm.setMainId(id);
        itm.setSystem(1);
        List<CourseItemConfigVo> list = courseItemConfigService.selectCourseItemConfigList(itm);
        List<CourseItemConfigVo> list2 = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(list)){
            for (CourseItemConfigVo vo:list
            ) {
                vo.setMainId(newId);
                vo.setId(null);
                vo.setSchoolId(courseMainConfigVo.getSchoolId());
                list2.add(vo);

            }
            courseItemConfigService.batchInsertInfo(list2);
        }


        CourseItemTime ctime = new CourseItemTime();
        ctime.setMainId(id);
        List<CourseItemTime> timeList = courseItemTimeService.selectCourseItemTimeList(ctime);
        if(CollectionUtils.isNotEmpty(timeList)){
            List<CourseItemTime> timeList2 = new ArrayList<>();
            for (CourseItemTime tm:timeList
                 ) {
                tm.setMainId(newId);
                timeList2.add(tm);
            }
            courseItemTimeService.batchInsertInfo(timeList2);
        }


        return res;
    }

    @Log(title = "清除已生成的课表", businessType = BusinessType.OTHER)
    @RequiresPermissions("school:courseConfig:edit")
    @ResponseBody
    @GetMapping("/clearAllCourses/{id}")
    public AjaxResult clearAllCourses(@PathVariable("id") Long id)
    {
        AjaxResult res = AjaxResult.success();
        CourseMainConfigVo courseMainConfigVo = courseMainConfigService.selectCourseMainConfigById(id);
        courseItemConfigService.deleteCourseItemConfigByMainIdWhereSystem0(id);
        courseMainConfigVo.setState(0);
        courseMainConfigService.updateCourseMainConfig(courseMainConfigVo);
        return res;
    }

    @Log(title = "生成完整课表", businessType = BusinessType.OTHER)
    @RequiresPermissions("school:courseConfig:edit")
    @ResponseBody
    @GetMapping("/makeAllCourses/{id}")
    public AjaxResult makeAllCourses(@PathVariable("id") Long id)
    {
        AjaxResult res = AjaxResult.success();
        CourseItemConfigVo itm = new CourseItemConfigVo();
        itm.setMainId(id);
        itm.setSystem(1);
        //查询状态是1的基础课表
        List<CourseItemConfigVo> list = courseItemConfigService.selectCourseItemConfigList(itm);
        if(CollectionUtils.isNotEmpty(list)){
            //清空状态是0的课表
            courseItemConfigService.deleteCourseItemConfigByMainIdWhereSystem0(id);
            Map<String,CourseItemConfigVo> baseCourseMap = new HashMap<>();
            List<Long> clazzList = new ArrayList();
            for(int i=0;i<list.size();i++){
                CourseItemConfigVo item = list.get(i);
                String key = String.format("%s:%s:%s:%s",item.getType(),item.getWeek(),item.getSection(),item.getClazzId());
                baseCourseMap.put(key,item);
                if(!clazzList.contains(item.getClazzId())){
                    clazzList.add(item.getClazzId());
                }

            }
            List<CourseItemConfigVo> list2 = new ArrayList<>();
            CourseMainConfigVo courseMainConfigVo = courseMainConfigService.selectCourseMainConfigById(id);
            int days = DateUtils.getDaySum(courseMainConfigVo.getBgDate(),courseMainConfigVo.getEdDate());
            Calendar cal = Calendar.getInstance();
            int allZS = 1;//周数
            int circle = courseMainConfigVo.getWeeks();//几周一个循环
            int nodes = courseMainConfigVo.getSections();
            for(int i=0;i<days;i++){
                Date d0 = DateUtils.addDays(courseMainConfigVo.getBgDate(),i);
                cal.setTime(d0);
                int wk = DateUtils.getCurrWeerk(d0);//星期几
                if((wk==7||wk==6)&&i==0){
                    continue;
                }
                if((wk==7)&&i==1){
                    continue;
                }
                int zs = 1;
                if(circle<=1){
                    zs = 1;
                }else{
                    zs = allZS/circle;
                    if(zs==0){
                        zs = circle;
                    }
                }
                for(Long clazzId:clazzList){
                    for(int k = 1;k<=nodes;k++){
                        String key = String.format("%s:%s:%s:%s",zs,wk,k,clazzId);
                        if(baseCourseMap.containsKey(key)){
                            CourseItemConfigVo itemv = baseCourseMap.get(key);
                            CourseItemConfigVo itemv1 = itemv.clone();
                            itemv1.setCourseDay(d0);
                            itemv1.setSystem(0);
                            itemv1.setType(allZS);
                            itemv1.setSchoolId(courseMainConfigVo.getSchoolId());
                            list2.add(itemv1);
                        }
                    }
                }


                if(wk==7){
                    allZS+=1;
                }

            }

            if(list2.size()>0){
                courseItemConfigService.batchInsertInfo(list2);
            }
            courseMainConfigVo.setState(1);
            courseMainConfigService.updateCourseMainConfig(courseMainConfigVo);

        }else{
            res = AjaxResult.error("请先设定课程信息！");
        }

        return res;
    }


    //clearAllCourses
    @RequiresPermissions("school:courseConfig:edit")
    @GetMapping("/makeCourse/{id}")
    public String makeCourseById(@PathVariable("id")Long id,ModelMap modelMap)
    {
        CourseMainConfigVo config = courseMainConfigService.selectCourseMainConfigById(id);
        ClassInfo info = new ClassInfo();
        info.setDeptId(SchoolUtil.getSchoolId());
        info.setGradeId(config.getGradeId());
        List<ClassInfo> clazzList = classInfoService.selectClassInfoList(info);
        modelMap.put("configVo",config);
        modelMap.put("clazzList",clazzList);
        String[] weekList = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
        modelMap.put("clazzList",clazzList);
        modelMap.put("weekList",weekList);
        JSONObject weeksDatas = new JSONObject();
        JSONArray array = getWeekCourses(config, clazzList, 1);
        weeksDatas.put("w"+1,array);
        modelMap.put("weeksDatas",weeksDatas);
        return prefix + "/makeCourse";
    }

    @GetMapping("/makeCourseTime/{id}")
    public String makeCourseTimeById(@PathVariable("id")Long id,ModelMap modelMap)
    {
        CourseMainConfigVo config = courseMainConfigService.selectCourseMainConfigById(id);
        modelMap.put("configVo",config);

        CourseItemTime cTime = new CourseItemTime();
        cTime.setMainId(id);
        List<CourseItemTime> list = courseItemTimeService.selectCourseItemTimeList(cTime);
        List<CourseItemTime> list2 = new ArrayList<>();
        for(int i=1;i<=config.getSections();i++){
            CourseItemTime it = findCourseItemTime(i,list);
            list2.add(it);
        }
        modelMap.put("timeList",list2);
        return prefix + "/makeCourseTime";
    }

    @Log(title = "设定课程时间信息", businessType = BusinessType.OTHER)
    @PostMapping("/saveCourseTime")
    @ResponseBody
    public AjaxResult saveCourseTime(CourseItemTime courseItemTime)
    {
        AjaxResult result = AjaxResult.success();
        logger.info(courseItemTime.toString());
        if(courseItemTime.getMainId()==null||courseItemTime.getSection()==null){
            result = AjaxResult.error("非法调用");
        }else{
            CourseItemTime ct = new CourseItemTime();
            ct.setSection(courseItemTime.getSection());
            ct.setMainId(courseItemTime.getMainId());
            List<CourseItemTime> list = courseItemTimeService.selectCourseItemTimeList(ct);
            if(list!=null&&list.size()>0){
                ct = list.get(0);//只能查出一个来
                ct.setBTime(courseItemTime.getBTime());
                ct.setETime(courseItemTime.getETime());
                courseItemTimeService.updateCourseItemTime(ct);
            }else{
                int id = courseItemTimeService.insertCourseItemTime(courseItemTime);
                courseItemTime.setId((long) id);
            }
        }
        return result;
    }

    public CourseItemTime findCourseItemTime(int node,List<CourseItemTime> list){
        CourseItemTime timeItem = new CourseItemTime();
        if(list!=null&&list.size()>0){
            for (CourseItemTime time:list
                 ) {
                int k = time.getSection();
                if(k == node){
                    timeItem = time;
                    break;
                }
            }
        }else{
            timeItem.setId((long) -node);
            timeItem.setSection(node);
        }
        return timeItem;
    }

    private JSONArray getWeekCourses(CourseMainConfigVo config, List<ClassInfo> clazzList,int weekId) {
        JSONArray array = new JSONArray();
        int len = config.getSections();
        for(int i = 1;i <= len;i++){
            JSONObject gr0 = new JSONObject();
            gr0.put("section",i);
            for(int j=0;j<clazzList.size();j++){
                ClassInfo info1 = clazzList.get(j);
                JSONArray clazz = new JSONArray();
                //根据Id,clazz查询课程信息
                CourseItemConfigVo item = new CourseItemConfigVo();
                item.setClazzId(info1.getId());
                item.setSection(i);
                item.setWeek(weekId);
                item.setMainId(config.getId());
                List<CourseItemConfigVo> list = courseItemConfigService.selectCourseItemConfigList(item);
                if(list!=null&&list.size()>0){
                    for (CourseItemConfigVo itemConfig:list ) {
                        JSONObject c0 = new JSONObject();
                        c0.put("cId",itemConfig.getCourseId());
                        List<SysDictData> listDict = dictService.getType("sc_subject_type");
                        for (SysDictData data:listDict) {
                            if(data.getDictValue().equals(itemConfig.getCourseId()+"")){
                                c0.put("cName",data.getDictLabel());
                            }
                        }
                        c0.put("tId",itemConfig.getTeacherId());
                        c0.put("wId",itemConfig.getType());
                        c0.put("weekId",weekId);
                        clazz.add(c0);
                    }
                }
                if(clazz.size()>0)
                    gr0.put("g"+info1.getId(),clazz);
            }
            array.add(gr0);
        }
        return array;
    }

    @Log(title = "设定课程信息", businessType = BusinessType.OTHER)
    @PostMapping("/saveCourse")
    @ResponseBody
    public AjaxResult saveCourse(CourseItemInfoVo courseItemInfoVo)
    {
        AjaxResult result = AjaxResult.success();
        if(courseItemInfoVo.getList()!=null&&courseItemInfoVo.getList().size()>0){
            for (CourseItemInfoVo ivo:courseItemInfoVo.getList()) {
                CourseItemConfigVo itemConfig = new CourseItemConfigVo();
                itemConfig.setMainId(courseItemInfoVo.getMainId());//mainId
                itemConfig.setWeek(courseItemInfoVo.getWeekId());//周几
                itemConfig.setSection(courseItemInfoVo.getSection());//第几节课
                itemConfig.setClazzId(courseItemInfoVo.getClazzId());
                itemConfig.setType(ivo.getWId());//第几周
                List<CourseItemConfigVo> courses = courseItemConfigService.selectCourseItemConfigList(itemConfig);
                if(courses==null||courses.size()==0){
                    if(ivo.getCId()!=null){
                        itemConfig.setCourseId(ivo.getCId());
                        itemConfig.setTeacherId(ivo.getTId());
                        itemConfig.setSchoolId(SchoolUtil.getSchoolId());
                        itemConfig.setCreateBy(ShiroUtils.getSysUser().getUserName());
                        itemConfig.setCreateTime(DateUtils.getNowDate());
                        courseItemConfigService.insertCourseItemConfig(itemConfig);
                    }
                }else{
                        itemConfig = courses.get(0);
                    if(ivo.getCId()==null){
                        courseItemConfigService.deleteCourseItemConfigById(itemConfig.getId());
                    }else{
                        itemConfig.setCourseId(ivo.getCId());
                        itemConfig.setTeacherId(ivo.getTId());
                        itemConfig.setUpdateBy(ShiroUtils.getSysUser().getUserName());
                        itemConfig.setUpdateTime(DateUtils.getNowDate());
                        courseItemConfigService.updateCourseItemConfig(itemConfig);
                    }

                }
            }
        }
        return result;
    }

    @GetMapping("/getWeeksCourseData/{id}/{wid}")
    @ResponseBody
    public JSONObject getWeeksCourseData(@PathVariable("id")Long id,@PathVariable("wid")Integer wid)
    {
        CourseMainConfigVo config = courseMainConfigService.selectCourseMainConfigById(id);
        ClassInfo info = new ClassInfo();
        info.setDeptId(SchoolUtil.getSchoolId());
        info.setGradeId(config.getGradeId());
        List<ClassInfo> clazzList = classInfoService.selectClassInfoList(info);
        JSONObject weeksData = new JSONObject();
        JSONArray array = getWeekCourses(config, clazzList, wid);
        weeksData.put("w"+wid,array);
        return weeksData;
    }

    public int findIndexCourseId(CourseItemConfig configItem,int weeks){
        int index = 0;
        for(int i=1;i<=weeks;i++){
            if(configItem.getType() ==i){
                index = i;
                break;
            }
        }
        return index;
    }


    @GetMapping("/checkClasses/{id}")
    @ResponseBody
    public AjaxResult checkClassesById(@PathVariable("id")Long id)
    {
        CourseMainConfigVo config = courseMainConfigService.selectCourseMainConfigById(id);
        ClassInfo info = new ClassInfo();
        info.setDeptId(SchoolUtil.getSchoolId());
        info.setGradeId(config.getGradeId());
        List<ClassInfo> clazzList = classInfoService.selectClassInfoList(info);
        AjaxResult rest = AjaxResult.success();
        if(clazzList==null||clazzList.size()==0){
            rest = AjaxResult.warn("没有班级信息！");
        }
        return rest;
    }

    /**
     * 修改保存排课规则主
     */
    @RequiresPermissions("school:courseConfig:edit")
    @Log(title = "排课规则主", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(CourseMainConfigVo courseMainConfig)
    {
        courseMainConfig.setUpdateBy(ShiroUtils.getSysUser().getUserName());
        courseMainConfig.setUpdateTime(DateUtils.getNowDate());
        return toAjax(courseMainConfigService.updateCourseMainConfig(courseMainConfig));
    }

    /**
     * 删除排课规则主
     */
    @RequiresPermissions("school:courseConfig:remove")
    @Log(title = "排课规则主", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        int k = courseMainConfigService.deleteCourseMainConfigByIds(ids);
        courseItemConfigService.deleteCourseItemConfigByMainIds(ids);
        courseItemTimeService.deleteCourseItemTimeByMainIds(ids);
        return toAjax(k);
    }

    /**
     * 查询排课规则主列表
     */
    @GetMapping("/getRuleList")
    @ResponseBody
    public List<CourseMainConfigVo> getRuleList()
    {
        CourseMainConfigVo courseMainConfig = new CourseMainConfigVo();
        courseMainConfig.setSchoolId(SchoolUtil.getSchoolId());
        return  courseMainConfigService.selectCourseMainConfigList(courseMainConfig);
    }

    /**
     * 按照班级排课记录查询
     */
    @GetMapping("/courseInfo")
    public String courseInfo(ModelMap modelMap)
    {
        ClassInfo info = new ClassInfo();
        info.setDeptId(SchoolUtil.getSchoolId());
        List<ClassInfo> clazzList = classInfoService.selectClassInfoList(info);
        modelMap.put("cList",clazzList);
        return prefix + "/courseInfo";
    }

    /**
     * 按照班级排课记录查询
     */
    @GetMapping("/courseInfoTeacher")
    public String courseInfoTeacher(ModelMap modelMap)
    {
        PersonnelInfo info = new PersonnelInfo();
        info.setDeptId(SchoolUtil.getSchoolId());
        List<PersonnelInfo> pList = personnelInfoService.selectUserList(info);
        modelMap.put("pList",pList);
        return prefix + "/courseInfoTeacher";
    }

    /**
     * 按照班级排课记录查询
     */
    @GetMapping("/courseInfoMul")
    public String courseInfoMul(ModelMap modelMap)
    {
        ClassInfo info = new ClassInfo();
        info.setDeptId(SchoolUtil.getSchoolId());
        List<ClassInfo> clazzList = classInfoService.selectClassInfoList(info);
        modelMap.put("cList",clazzList);
        return prefix + "/courseInfoMul";
    }

    @PostMapping("/getClazzCourseInfo")
    @ResponseBody
    public JSONArray getClazzCourseInfo(CourseItemConfigVo courseItemConfig)
    {
        JSONArray array = new JSONArray();
        int bw = Integer.parseInt(courseItemConfig.getParams().get("bType")+"");
        int ew = Integer.parseInt(courseItemConfig.getParams().get("eType")+"");
        if(bw>ew){
            return array;
        }
        CourseMainConfigVo config = courseMainConfigService.selectCourseMainConfigById(courseItemConfig.getMainId());
        if(config==null){
            return array;
        }
        SysUser user = new SysUser();
        user.setDeptId(SchoolUtil.getSchoolId());
        List<SysUser> uList = sysUserService.selectUserList(user);
        Long clazzId = courseItemConfig.getClazzId();
        if(clazzId!=null){
            ClassInfo info = classInfoService.selectClassInfoById(courseItemConfig.getClazzId());
            getClazzInfoCourseScheduleByClazz(courseItemConfig, array, bw, ew, config, uList, info);
        }else {
            ClassInfo i0 = new ClassInfo();
            i0.setDeptId(SchoolUtil.getSchoolId());
            List<ClassInfo> list = classInfoService.selectClassInfoList(i0);
            for (ClassInfo ii:list
                 ) {
                getClazzInfoCourseScheduleByClazz(courseItemConfig, array, bw, ew, config, uList, ii);
            }
        }

        return array;
    }

    private void getClazzInfoCourseScheduleByClazz(CourseItemConfigVo courseItemConfig, JSONArray array, int bw, int ew, CourseMainConfigVo config, List<SysUser> uList, ClassInfo info) {
        int circle = config.getWeeks();//周期数
        HashMap<String, JSONObject> wkMap = new HashMap<>();
        for(int i=bw;i<=ew;i++){//按照周数循环取数
            int m = 1;
            if(circle!=1){
                m = i%circle;
                if(m==0){
                    m = circle;
                }
            }
            Date bg = config.getBgDate();//排课的开始时间

            Date[] ds = DateUtils.getBeginAndEndDate(i,bg);
            String subtitle = "("+DateUtils.dateTime(ds[0])+"~"+DateUtils.dateTime(ds[1])+")";
            courseItemConfig.setType(m);
            String id = config.getId()+"_"+info.getId()+"_"+m;
            JSONObject wi = new JSONObject();
            if(wkMap.containsKey(id)) {
                wi = (JSONObject) wkMap.get(id).clone();
            }else{
                courseItemConfig.setClazzId(info.getId());
                List<CourseItemConfigVo> list = courseItemConfigService.selectCourseItemConfigList(courseItemConfig);
                List<JSONObject> datas = getBaseJsonData(config.getSections());
                if(list!=null&&list.size()>0){
                    for (CourseItemConfigVo item:list) {
                        for (JSONObject j0:datas) {
                            if(item.getSection().equals(j0.getInteger("section"))){
                                Integer cId = item.getCourseId();
                                Integer wId = item.getWeek();
                                if(cId!=null){
                                    j0.put("w"+wId+"cId",cId);
                                    SysDictData data = findCourseInfo(cId);
                                    j0.put("w"+wId+"cName",data.getDictLabel());
                                    Long tId = item.getTeacherId();
                                    if(tId!=null){
                                        j0.put("w"+wId+"tId",tId);
                                        SysUser teacher = findUserInfo(tId,uList);
                                        if(teacher ==null){
                                            j0.put("w"+wId+"tName","-");
                                            j0.put("w"+wId,data.getDictLabel()+"(-)");
                                        }else{
                                            j0.put("w"+wId+"tName",teacher.getUserName());
                                            j0.put("w"+wId,data.getDictLabel()+"("+teacher.getUserName()+")");
                                        }

                                    }else{
                                        j0.put("w"+wId,data.getDictLabel()+"(-)");
                                    }
                                }
                            }
                        }
                    }
                }
                wi.put("list",datas);
                if(!wkMap.containsKey(id)){
                    wkMap.put(id,wi);
                }

            }
            wi.put("scheduleName","第"+i+"周课表"+subtitle);
            wi.put("typeName",info.getClassName());
            wi.put("mId",config.getId());
            wi.put("typeId",info.getId());
            wi.put("name",config.getName());
            wi.put("type",m);
            wi.put("weeks",i);
            wi.put("kid",id);
            array.add(wi);
        }
    }

    private SysUser findUserInfo(Long uId,List<SysUser> uList){
        SysUser u = null;
        for (SysUser u0:uList
             ) {
            if(u0.getUserId().equals(uId)){
                u = u0;
                break;
            }
        }
        return u;
    }

    @PostMapping("/getClazzCourseInfoTeacher")
    @ResponseBody
    public JSONArray getClazzCourseInfoTeacher(CourseItemConfigVo courseItemConfig)
    {
        JSONArray array = new JSONArray();
        int bw = Integer.parseInt(courseItemConfig.getParams().get("bType")+"");
        int ew = Integer.parseInt(courseItemConfig.getParams().get("eType")+"");
        if(bw>ew){
            return array;
        }
        PersonnelInfo info = personnelInfoService.selectUserById(courseItemConfig.getTeacherId());
        CourseMainConfigVo config = courseMainConfigService.selectCourseMainConfigById(courseItemConfig.getMainId());
        if(config==null){
            return array;
        }
        int circle = config.getWeeks();//周期数
        //TODO 查询个人请假
        AdjustCourse adjustCourse = new AdjustCourse();
        adjustCourse.setTeacherId(info.getUserId());
        adjustCourse.setStatus(null);
        //请假列表
        List<AdjustCourse> qjList = adjustCourseService.selectAdjustCourseList(adjustCourse);
        HashMap<String,Integer> qjMaps = new HashMap<>();
        if(qjList!=null&&qjList.size()>0){
            for (AdjustCourse c:qjList) {
                List<String> dateList = DateUtils.findDates(c.getBeginTime(), c.getEndTime());
                for (String d0:dateList) {
                    String key = d0;
                    int ball = 0;
                    int courseNo = 0;
                    if(c.getCourseNo()!=null){
                        courseNo = c.getCourseNo();
                    }
                    if(courseNo>0){
                        ball = 1;
                        key = key+"_"+c.getCourseNo();
                    }
                    qjMaps.put(key,ball);
                }
            }
        }
        //TODO 查询个人替课
        AdjustCourse adjustCourse1 = new AdjustCourse();
        adjustCourse1.setSubstituteTeacherId(info.getUserId()+"");
        adjustCourse1.setStatus(null);
        //替课列表
        List<AdjustCourse> tkList = adjustCourseService.selectAdjustCourseList(adjustCourse1);
        HashMap<String,JSONObject> wkMap = new HashMap<>();
        for(int i=bw;i<=ew;i++){//按照周数循环取数
            int m = 1;
            if(circle!=1){
                m = i%circle;
                if(m==0){
                    m = circle;
                }
            }
            courseItemConfig.setType(m);
            String id = config.getId()+"_"+info.getUserId()+"_"+m;
            JSONObject wi = new JSONObject();

            if(wkMap.containsKey(id)){
                wi = (JSONObject) wkMap.get(id).clone();
            }else{
                List<JSONObject> nodeList = getBaseJsonData(config.getSections());
                List<CourseItemConfigVo> list = courseItemConfigService.selectCourseItemConfigList(courseItemConfig);
                if(list!=null&&list.size()>0){
                    for (CourseItemConfigVo item:list) {
                        for (JSONObject j0:nodeList) {
                            if(item.getSection().equals(j0.getInteger("section"))){
                                Long cId = item.getClazzId();
                                int wId = item.getWeek();
                                ClassInfo classInfo = classInfoService.selectClassInfoById(cId);
                                if(cId!=null){
                                    j0.put("w"+wId+"clazzId",cId);
                                    String key = "w"+wId;
                                    String value = j0.getString(key);
                                    if(StringUtils.isNotEmpty(value)&&value.length()>0){
                                        value+="/"+classInfo.getClassName();
                                    }else{
                                        value = classInfo.getClassName();
                                    }
                                    j0.put("w"+wId,value);
                                }
                            }
                        }
                    }
                }

                wi.put("list",nodeList);
                if(!wkMap.containsKey(id)){
                    JSONObject w2 = new JSONObject();
                    String s1 = JSON.toJSONString(nodeList);
                    w2.put("list",JSON.parse(s1));
                    wkMap.put(id, w2);
                }
            }

            //获取当前周的开始时间和结束时间
            Date[] ddd = DateUtils.getBeginAndEndDate(i, config.getBgDate());
            String subtitle = "("+DateUtils.dateTime(ddd[0])+"~"+DateUtils.dateTime(ddd[1])+")";
            List<String> dateList = DateUtils.findDates(ddd[0], ddd[1]);

            //请假搞一次
            List<JSONObject> nodeList1 = (List<JSONObject>) wi.get("list");
            String s1 = JSON.toJSONString(nodeList1);
            List<JSONObject>  nodeList = (List<JSONObject>) JSON.parse(s1);
            for(int mm=1;mm<8;mm++){
                String d1 = dateList.get(mm-1);
                if(qjMaps.containsKey(d1)){
                    //全天请假
                    for (JSONObject jnode:nodeList) {
                        String cname = jnode.getString("w"+mm);
                        if(StringUtils.isNotEmpty(cname)){
//                            jnode.put("w"+mm,"(请假)");
                            jnode.put("w"+mm+"_s",-1);
                        }
                    }
                }else{
                    for (JSONObject jnode:nodeList) {
                        String key = d1+"_"+jnode.getInteger("section");
                        if(qjMaps.containsKey(key)){
                            String cname = jnode.getString("w"+mm);
                            if(StringUtils.isNotEmpty(cname)){
//                                jnode.put("w"+mm,"(请假)");
                                jnode.put("w"+mm+"_s",-1);
                            }
                        }
                    }
                }
                wi.put("list",nodeList);
            }
            //替课搞一次
            if(CollectionUtils.isNotEmpty(tkList)){
                for(AdjustCourse course:tkList){
                    long teacherId = course.getTeacherId();//被替课老师的Id
                    int nodeId = course.getCourseNo()==null?0:course.getCourseNo();//第几节课，如果为0则全天
                    Date bg1 = course.getBeginTime();//请假开始时间
                    Date end = course.getEndTime();//请假结束时间
                    CourseItemConfigVo cvo = new CourseItemConfigVo();
                    cvo.setMainId(config.getId());
                    cvo.setTeacherId(teacherId);
                    if(nodeId>0){
                        cvo.setSection(nodeId);
                    }
                    cvo.setSystem(0);//查询做了排课明细的
                    cvo.setType(i);//第几周
                    Map<String,Object> othMap = new HashMap<>();
                    othMap.put("beginDate",bg1);//开始周
                    othMap.put("endDate",end);//结束周
                    cvo.setParams(othMap);
                    List<CourseItemConfigVo> pkList = courseItemConfigService.selectCourseItemConfigList(cvo);
                    for(CourseItemConfigVo vo1 : pkList){
                        int nodeId1 = vo1.getSection();
                        Long classId = vo1.getClazzId();
                        Integer v1 = vo1.getWeek();//周几
                        for (JSONObject jnode:nodeList) {
                            if(nodeId1 == jnode.getInteger("section")){
                                ClassInfo c1 = classInfoService.selectClassInfoById(classId);
                                if(c1!=null){
                                    jnode.put("w"+v1+"_s",1);
                                    jnode.put("w"+v1,c1.getClassName());
                                }
                            }
                        }
                    }
                }
                wi.put("list",nodeList);
            }

            wi.put("scheduleName","第"+i+"周课表"+subtitle);
            wi.put("name",config.getName());
            wi.put("typeName",info.getUserName());
            wi.put("mId",config.getId());
            wi.put("typeId",info.getUserId());
            wi.put("type",m);
            wi.put("weeks",i);
            wi.put("kid",id);
            array.add(wi);
        }
        return array;
    }


    @GetMapping("/pdfRowTeacher/{id}/{week}")
    public String pdfItemTeacher(@PathVariable("id") String id,@PathVariable("week")Integer week,ModelMap mmap) {
        String[] ids = id.split("_");
        Long configId = Long.parseLong(ids[0]);
        Long teacherId = Long.parseLong(ids[1]);
        CourseItemConfigVo courseItemConfig = new CourseItemConfigVo();
        courseItemConfig.setMainId(configId);
        courseItemConfig.setTeacherId(teacherId);
        HashMap<String,Object> params = new HashMap();
        params.put("bType",week);
        params.put("eType",week);
        courseItemConfig.setParams(params);
        JSONArray list = getClazzCourseInfoTeacher(courseItemConfig);
//        printCourse(response, list);
        mmap.put("list",list);
        String name = "";
        if(list.size()>0){
            JSONObject j0 = list.getJSONObject(0);
            name = j0.getString("name");
        }
        mmap.put("name",name);
//        printCourse(response, list);
        return prefix+"/print";
//        return null;
    }


    @GetMapping("/pdfRowClazz/{id}/{week}")
    public String pdfRowClazz(@PathVariable("id") String id,@PathVariable("week")Integer week, ModelMap mmap) {
        String[] ids = id.split("_");
        Long configId = Long.parseLong(ids[0]);
        Long clazzId = Long.parseLong(ids[1]);
        CourseItemConfigVo courseItemConfig = new CourseItemConfigVo();
        courseItemConfig.setMainId(configId);
        courseItemConfig.setClazzId(clazzId);
        HashMap<String,Object> params = new HashMap();
        params.put("bType",week);
        params.put("eType",week);
        courseItemConfig.setParams(params);
        JSONArray list = getClazzCourseInfo(courseItemConfig);
        mmap.put("list",list);
        String name = "";
        if(list.size()>0){
            JSONObject j0 = list.getJSONObject(0);
            name = j0.getString("name");
        }
        mmap.put("name",name);
//        printCourse(response, list);
        return prefix+"/print";
    }

    @GetMapping("/pdfAll/{mid}/{tId}/{type}")
    public String pdfAll(@PathVariable("mid") Long id,@PathVariable("tId")String tId,@PathVariable("type")Integer type, ModelMap mmap) {
        CourseItemConfigVo courseItemConfig = new CourseItemConfigVo();
        courseItemConfig.setMainId(id);
        String[] keys = tId.split("_");
        long ltId = Long.parseLong(keys[0]);
        if(type==1){
            courseItemConfig.setTeacherId(ltId);
        }else{
            courseItemConfig.setClazzId(ltId);
        }
        int bw = Integer.parseInt(keys[1]);
        int ew = Integer.parseInt(keys[2]);
        if(bw>ew){
            int k = bw;
            bw = ew;
            ew = k;
        }
        CourseMainConfigVo config = courseMainConfigService.selectCourseMainConfigById(id);
        HashMap<String,Object> params = new HashMap();
        params.put("bType",bw);
        params.put("eType",ew);
        courseItemConfig.setParams(params);
        JSONArray list = null;
        if(type==1){
            list = getClazzCourseInfoTeacher(courseItemConfig);
        }
        else{
            list = getClazzCourseInfo(courseItemConfig);
        }
//        printCourse(response, list);
        mmap.put("list",list);
        String name = "";
        if(list.size()>0){
            JSONObject j0 = list.getJSONObject(0);
            name = j0.getString("name");
        }
        mmap.put("name",name);
        return prefix+"/print";
    }

    private void printCourse(HttpServletResponse response, JSONArray list) {
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/png");
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            String temp = Global.getDownloadPath() + "temp";
            File file = new File(temp);
            if (!file.exists()) {
                file.mkdirs();
            }
            String fullName = PdfUtil.createCourseSchedulePdf(list, temp);
            File f0 = new File(fullName);
            if (f0.exists()) {
                String headerKey = "Content-Disposition";
                String headerValue = String.format("attachment; filename=\"%s\"",
                        f0.getName());
                response.setHeader(headerKey, headerValue);
                InputStream myStream = new FileInputStream(fullName);
                int byteread = -1;
                byte[] buffer = new byte[1024];
                while ((byteread = myStream.read(buffer)) != -1) {
                    out.write(buffer, 0, byteread);
                }
                myStream.close();
                out.flush();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (out != null){
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @GetMapping("/pdfAll2/{key}/{type}")
    public String pdfAll2(@PathVariable("key") String key,@PathVariable("type")Integer type, ModelMap mmap) {
        if(StringUtils.isNotEmpty(key)){
            String[] idKeys = key.split("_");
            Long id = Long.parseLong(idKeys[0]);
            Long tId = Long.parseLong(idKeys[1]);
            Integer bg = Integer.parseInt(idKeys[2]);
            Integer ed = Integer.parseInt(idKeys[3]);
            CourseItemConfigVo courseItemConfig = new CourseItemConfigVo();
            courseItemConfig.setMainId(id);
            HashMap<String,Object> params = new HashMap();
            params.put("bType",bg);
            params.put("eType",ed);
            courseItemConfig.setParams(params);
            JSONArray list = null;
            if(tId == -1){
                courseItemConfig.setClazzId(null);
            }else{
                courseItemConfig.setClazzId(tId);
            }
            list = getClazzCourseInfo(courseItemConfig);
//            printCourse(response, list);
            mmap.put("list",list);
            String name = "";
            if(list.size()>0){
                JSONObject j0 = list.getJSONObject(0);
                name = j0.getString("name");
            }
            mmap.put("name",name);
            return prefix+"/print";
        }

        return prefix+"/print";
    }

    private List<JSONObject> getBaseJsonData(int nodes) {
        List<JSONObject> datas = new ArrayList<>();
        for (int i = 1; i <= nodes; i++) {
            JSONObject j0 = new JSONObject();
            j0.put("section", i);
            for (int k = 1; k < 8; k++) {
                j0.put("w" + k, "");
            }
            datas.add(j0);
        }
        return datas;
    }

    public SysDictData findCourseInfo(Integer k){
        List<SysDictData> listDict = dictService.getType("sc_subject_type");
        SysDictData dictData = null;
        for (SysDictData dictData1:listDict){
            if(Integer.parseInt(dictData1.getDictValue())==k){
                dictData = dictData1;
                break;
            }
        }
        return dictData;
    }

    /**
     * 新增排课基础
     */
    @GetMapping("/count")
    public String count(ModelMap modelMap)
    {
        PersonnelInfo info = new PersonnelInfo();
        info.setDeptId(SchoolUtil.getSchoolId());
        List<PersonnelInfo> pList = personnelInfoService.selectUserList(info);
        modelMap.put("pList",pList);
        return prefix + "/courseCount";
    }
    /**
     * 查询排课基础列表
     */
    @RequiresPermissions("school:courseConfig:list")
    @PostMapping("/countStatics")
    @ResponseBody
    public TableDataInfo count(CourseStatisticsVo courseStatisticsVo)
    {
        startPage();
        List<CourseStatisticsVo> list = courseItemConfigService.selectCourseStatistics(courseStatisticsVo);
        CourseMainConfigVo main = courseMainConfigService.selectCourseMainConfigById(courseStatisticsVo.getId());
        for (CourseStatisticsVo item:list) {
            int total = 0,disCount=0,addCount=0;
            int base = item.getBaseCount();
            //获取请假调课数 -- 要减去
            disCount = getAdjstAddCount(main,item,true);
            //获取替课数据  -- 要增加总数
            addCount = getAdjstAddCount(main, item, false);
            total = base+addCount-disCount;
            item.setTotal(total);
            item.setDisCount(disCount);
            item.setOtherCount(addCount);
        }
        return getDataTable(list);
    }

    private int getAdjstAddCount(CourseMainConfigVo main, CourseStatisticsVo item,boolean isQJ) {
        int count = 0;
        AdjustCourse adj2 = new AdjustCourse();
        if(isQJ){
            adj2.setTeacherId(item.getTeacherId());
        }else{
            adj2.setSubstituteTeacherId(item.getTeacherId()+"");
        }
        adj2.setGradeId(main.getGradeId());
        Map<String,Object> map2 = new HashMap<>();
        map2.put("beginTime",main.getBgDate());
        map2.put("endTime",main.getEdDate());
        adj2.setParams(map2);
        adj2.setStatus(null);
        List<AdjustCourse> adjList2 = adjustCourseService.selectAdjustCourseList(adj2);
        if(CollectionUtils.isNotEmpty(adjList2)){
            for (AdjustCourse aj:adjList2) {
                CourseItemConfigVo vo = new CourseItemConfigVo();
                vo.setSystem(1);
                vo.setMainId(main.getId());
                vo.setTeacherId(aj.getTeacherId());
                vo.setSection(aj.getCourseNo());//第几节
                vo.setClazzId(aj.getClassId());
                vo.setCourseId(aj.getSubject());
                Map<String,Object> param = new HashMap<>();
                param.put("beginDate",aj.getBeginTime());
                param.put("endDate",aj.getEndTime());
                vo.setParams(param);
                List<CourseItemConfigVo> list = courseItemConfigService.selectCourseItemConfigList(vo);
                if(list!=null){
                    count+=list.size();
                }
            }
        }
        return count;
    }

    /**
     * 获取排课列表
     */
    @PostMapping("/courseMList")
    @ResponseBody
    public List<CourseMainConfigVo> courseMList() {
        CourseMainConfigVo item = new CourseMainConfigVo();
        item.setState(1);
        return courseMainConfigService.selectCourseMainConfigList(item);
    }


}
